Skip to content

[#564] Auto-save draft content on /create page#572

Merged
realproject7 merged 3 commits intomainfrom
task/564-draft-autosave
Mar 26, 2026
Merged

[#564] Auto-save draft content on /create page#572
realproject7 merged 3 commits intomainfrom
task/564-draft-autosave

Conversation

@realproject7
Copy link
Copy Markdown
Owner

Summary

  • useDraft hook — generic localStorage auto-save with 1-second debounce, restore on mount, beforeunload warning, clear/discard helpers
  • Create Storyline form — auto-saves title, content, genre, language to plotlink_draft_create
  • Chain Plot form — auto-saves title, content to plotlink_draft_plot_{storylineId}
  • "Draft restored" banner — shown for 3 seconds when content is recovered on page revisit
  • "Discard draft" button — clears saved content and resets form fields
  • Auto-clear on publish — drafts cleared via useEffect when state reaches "published"
  • beforeunload warning — browser prompts before navigating away with unsaved content

Fixes #564

Test plan

  • Write content on /create, refresh page → draft restored with indicator
  • Write content, close tab, reopen → draft restored
  • Publish storyline → draft cleared from localStorage
  • Click "Discard draft" → form cleared, localStorage cleared
  • Try to navigate away with content → browser warns
  • Chain plot draft saves per-storyline key
  • Build passes (npm run build)

🤖 Generated with Claude Code

- Add useDraft hook: debounced localStorage save (1s), restore on mount,
  beforeunload warning, clear/discard helpers
- Create Storyline form: auto-saves title, content, genre, language
  (key: plotlink_draft_create)
- Chain Plot form: auto-saves title, content
  (key: plotlink_draft_plot_{storylineId})
- "Draft restored" banner shown for 3s on page revisit
- "Discard draft" button to clear saved content
- Drafts cleared automatically on successful publish

Fixes #564

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@vercel
Copy link
Copy Markdown

vercel Bot commented Mar 26, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

1 Skipped Deployment
Project Deployment Actions Updated (UTC)
plotlink Ignored Ignored Mar 26, 2026 4:41pm

Request Review

Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

REQUEST CHANGES — Rules of Hooks violation.

src/app/create/page.tsx:278-281: The two useEffect calls for clearing drafts on publish are placed AFTER the early return at if (!isConnected) return. React hooks must be called in the same order on every render. When isConnected changes from false to true, React will see additional hooks and throw an error. Move these useEffects above the early return, alongside the other hooks.

Minor (non-blocking): discardDraft in useDraft.ts eslint-disables the exhaustive-deps rule and omits currentValues — since it only checks typeof for resetting, this works but is fragile.

useEffect for clearing drafts on publish must be called before the
!isConnected early return to maintain consistent hook call order.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: REQUEST CHANGES

Summary

The autosave hook covers the basic save/restore flow, but the current chain-plot implementation still leaks one storyline's draft into another storyline's storage key.

Findings

  • [high] When the chain plot storylineId changes, useDraft re-runs with a new key, but if that new key has no saved draft it just returns early without clearing the previous form state. The old storyline's title / content remain in React state, and the debounced save then writes those stale values into the new storyline-specific key. That breaks the requirement that chain-plot drafts be isolated per storyline.
    • File: src/app/create/page.tsx:186
    • File: src/hooks/useDraft.ts:24
    • File: src/hooks/useDraft.ts:63
    • Suggestion: when the draft key changes and there is no saved draft for that key, reset the bound fields to their empty/default values before the autosave effect can persist the previous storyline's content under the new key.

Decision

Requesting changes because the current implementation can overwrite one storyline's draft with another storyline's content, so the storyline-specific draft behavior is not correct yet.

Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

T2b approves. Rules of Hooks violation fixed — useEffect calls now correctly placed before early return. useDraft hook is clean with proper debounce, restore, and beforeunload handling.

Prevents stale content from storyline A being saved under storyline B's
draft key when switching storylines. Tracks previous key with a ref and
resets bound fields if no draft exists for the new key.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Copy link
Copy Markdown
Collaborator

@project7-interns project7-interns left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verdict: APPROVE

Summary

The remaining autosave issues are fixed. The draft hook now resets bound fields when the storyline-specific key changes and no draft exists for the new key, so chain-plot drafts no longer bleed across storylines, and the Rules-of-Hooks issue is already addressed.

Findings

  • None.

Decision

Approving because the debounced localStorage autosave, restore/discard flow, beforeunload warning, and storyline-specific draft isolation now satisfy the Batch 26 / #564 requirements.

@realproject7 realproject7 merged commit 47144ea into main Mar 26, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Auto-save draft content on /create page to prevent accidental data loss

2 participants